package me.spring.cloud.common.components.dds;

import me.spring.cloud.common.components.dds.context.ConfigPropertiesBinder;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.util.StringUtils;

/**
 * 数据源管理器,用于创建数据源
 *
 * @author luffy
 */
@Slf4j
public class DataSourceManager {

  @Autowired
  private ConfigPropertiesBinder binder;

  @Autowired
  private DataSourceProperties dataSourceProperties;

  /**
   * 创建hikari 数据源
   *
   * @see HikariDataSource
   */
  public HikariDataSource createDataSource() throws SQLException {
    HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class)
        .build();
    if (StringUtils.hasText(dataSourceProperties.getName())) {
      dataSource.setPoolName(dataSourceProperties.getName());
    }
    Bindable<?> target = Bindable.of(HikariDataSource.class).withExistingValue(dataSource);
    this.binder.bind("spring.datasource.hikari", target);
    this.testConnection(dataSource);
    return dataSource;
  }

  /**
   * 创建并测试数据源。如果连接失败则抛出异常
   *
   * @Return
   */
  public HikariDataSource createAndTestDataSource() throws SQLException {
    HikariDataSource newDataSource = createDataSource();
    this.testConnection(newDataSource);
    return newDataSource;
  }

  /**
   * 测试数据源
   *
   * @param dataSource
   */
  private void testConnection(HikariDataSource dataSource) throws SQLException {
    try {
      //获取连接
      Connection connection = dataSource.getConnection();
      //释放连接
      connection.close();
    } catch (SQLException ex) {
      log.error("Testing connection for data source failed: {}", dataSource.getJdbcUrl(), ex);
      dataSource.close();
      throw ex;
    }
  }
}
